/*
  跳石头
  题目描述
    一年一度的 “跳石头” 比赛又要开始了!
    这项比赛将在一条笔直的河道中进行，河道中分布着一些巨大岩石。
    组委会已经选择好了两块岩石作为比赛起点和终点。
    在起点和终点之间，有 N 块岩石（不含起点和终点的岩石）。
    在比赛过程中，选手们将从起点出发，每一步跳向相邻的岩石，直至到达终点。
    为了提高比赛难度，组委会计划移走一些岩石，使得选手们在比赛过程中的最短跳跃距离尽可能长。
    由于预算限制，组委会至多从起点和终点之间移走 M 块岩石（不能移走起点和终点的岩石）。
  输入格式
    第一行包含三个整数 L, N, M，分别表示起点到终点的距离，起点和终点之间的岩石数，以及组委会至多移走的岩石数。
      保证 L ≥ 1 且 N ≥ M ≥ 0。
    接下来 N 行，每行一个整数，第 i 行的整数 Di( 0 < Di < L)，表示第 i 块岩石与起点的距离。
      这些岩石按与起点距离从小到大的顺序给出，且不会有两个岩石出现在同一个位置。
  输出格式
    一个整数，即最短跳跃距离的最大值。
  输入数据 1
    25 5 2
    2
    11
    14
    17
    21
  输出数据 1
    4
  提示
    输入输出样例 1 说明：
      将与起点距离为 2 和 14 的两个岩石移走后, 最短的跳跃距离为 4
       (从与起点距离 17 的岩石跳到距离 21 的岩石, 或者从距离 21 的岩石跳到终点)。
    另：
      对于 20% 的数据, 0 ≤ M ≤ N ≤ 10。
      对于 50% 的数据, 0 ≤ M ≤ N ≤ 100。
      对于 100% 的数据, 0 ≤ M ≤ N ≤ 50,000, 1 ≤ L ≤ 1,000,000,000。
 【来源】NOIP 2015 提高组复赛 day2。
*/

#include <bits/stdc++.h>

using namespace std;

/*
  思路:
    通常采用二分答案算法的话, 需要首先明确 2 个核心问题:
      1) 答案的取值范围(区间)，即确定区间的最大值和最小值
      2) 判断某个答案是否满足题意(条件)的判定方法
    解答本题时，先明确出这 2 个问题:
      1）答案的取值范围(区间)
          区间的最小值: 最开始 n 个岩石中，相邻的 2 个岩石的距离的最小值；
                       特别注意: 本文件中的代码实现中使用 1 作为区间的最小值(最小的正整数为 1)，也符合条件!
          区间的最大值: 起点到终点的距离；
      2) 判断某个答案是否满足题意的判定方法:
          从离起点最近的岩石 (编号为 1) 开始找起，遍历每个岩石，
            如果从上一个位置到该岩石的距离小于答案，说明要挪走该岩石，并记录挪走岩石的个数
          遍历完成后，如果记录的要挪走的岩石的个数大于 m，则说明该答案不满足条件；
                     反之，则说明该答案满足条件!
*/

int L, n, M;
int a[500005] = {}; // a[i] 表示第 i 块岩石到起点的距离 (其中 i > 0)
int s = 1, e;       // s(start) 表示二分答案算法实现中进行二分查找时的开始边界(左边界)
                    // e(end)   表示二分答案算法实现中进行二分查找时的结束边界(右边界)

// 该函数用来判断输入 x(表示答案，即最短跳跃距离) 是否满足条件(题目要求)
bool check(int x) {
    long long num = 0;  // 表示要挪走岩石的个数
    int f = 0;

    /*
      遍历每个岩石，检查从上一个位置跳到该岩石的距离
      如果从上一个位置跳到该岩石的距离小于 x，则说明要把该岩石挪走，记录要挪走岩石的个数
    */
    for (int i = 1; i <= n; i++ ){
        if (a[i] - a[f] < x) { // 如果从上一个位置跳到该岩石的距离小于 x，则说明要把该岩石挪走，记录要挪走岩石的个数
            num++;
        } else {
            f = i;
        }
    }

    /*
      如果记录的要挪走的岩石的个数大于 m，则说明该答案不满足条件；
      反之，则说明该答案满足条件!
    */
    return num <= M;
}

int main() {
    cin >> L >> n >> M;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }

    e = L;
    a[n + 1] = L;

    /*
      用二分查找法，在答案的区间范围内，查找满足题目要求的最大值
    */
    int ans = 0;
    while (s <= e) {
        int mid = (s + e) / 2;
        if (check(mid)) {
            ans = mid;
            s = mid + 1; // 由于需要答案尽可能地大，所以我们进一步从 mid 的右半区间进行查找
        } else {
            e = mid - 1; // mid 不满足题目要求，从 mid 的左半区间进行查找
        }
    }
    cout << ans;

    return 0;
}